package com.thingsgrid.device.mapper;

import com.thingsgrid.device.dto.DeviceMaintenanceRecordDTO;
import com.thingsgrid.device.entity.Device;
import com.thingsgrid.device.entity.Product;
import com.thingsgrid.device.entity.ProductType;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.aggregation.ProjectionOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

/**
 * 功能说明：
 *
 * @author 李龙飞
 * @since 2019/9/4 15:54
 */
@Slf4j
@Repository("deviceMaintenanceMapper")
@AllArgsConstructor
public class DeviceMaintenanceMapper {

	private MongoTemplate mongoTemplate;

	/**
	 *说明：获取设备列表
	 *@author lilongfei
	 *@since 2019/9/5 15:30
	 */
	public List<Device> getDeviceList(String productType, String productId, String deviceId, Integer currentPage, Integer pageSize){
		if(currentPage<=0){
			currentPage=1;
		}
		//左连接product表
		LookupOperation lookupOperation = LookupOperation.newLookup()
			.from("product")
			.localField("product_id")
			.foreignField("product_id")
			.as("deviceList");
		//查询条件
		Criteria criteria = new Criteria();
		if(!StringUtils.isEmpty(productType)){
			criteria.and("deviceList.product_type_id").is(productType);
		}
		if(!StringUtils.isEmpty(productId)){
			criteria.and("product_id").is(productId);
		}
		if(!StringUtils.isEmpty(deviceId)){
			criteria.and("device_id").is(deviceId);
		}
		MatchOperation matchOperation = new MatchOperation(criteria);
		ProjectionOperation project  = Aggregation.project("device_id","device_name","device_shadow","product_id");

		//条件查询和分页
		Aggregation aggregation = Aggregation.newAggregation(lookupOperation,matchOperation,project,
			Aggregation.skip((currentPage-1)*pageSize),Aggregation.limit(pageSize));
		return mongoTemplate.aggregate(aggregation,"device",Device.class).getMappedResults();
	}

	/**
	 *说明：统计数据总条数
	 *@author lilongfei
	 *@since 2019/9/6 15:56
	 */
	public Integer getCollectionCount(String productType,String productId,String collectionName){
		int count;
		if(!StringUtils.isEmpty(productId)){
			Query queryProduct = new Query(Criteria.where("product_id").is(productId));
			count = Integer.parseInt(String.valueOf(mongoTemplate.count(queryProduct,collectionName)));
		}else if(!StringUtils.isEmpty(productType)){
			Criteria criteria = new Criteria();
			Query querydevice = new Query();
			querydevice.addCriteria(Criteria.where("product_type_id").is(productType));
			List<Product> productList = mongoTemplate.find(querydevice,Product.class,"product");
			List<String> productIdList = new ArrayList<>();
			for(Product product:productList){
				productIdList.add(product.getProductId());
			}
			Query query = new Query(Criteria.where("product_id").in(productIdList));
			query.addCriteria(criteria);
			count = Integer.parseInt(String.valueOf(mongoTemplate.count(query,collectionName)));
		}else{
			count = Integer.parseInt(String.valueOf(mongoTemplate.count(new Query(),collectionName)));
		}
		return count;
	}


	/**
	 *说明：查询设备维护记录
	 *@author lilongfei
	 *@since 2019/9/5 20:37
	 */
	public List<DeviceMaintenanceRecordDTO> getDeviceMaintenanceRecordList(String productType, String productId,
																		   String deviceId, Integer currentPage, Integer pageSize){
		if(currentPage<=0){
			currentPage=1;
		}
		//左连接device表
		LookupOperation lookupOperation = LookupOperation.newLookup()
			.from("device")
			.localField("config_device_id")
			.foreignField("device_id")
			.as("deviceList");
		//左连接product表
		LookupOperation leftProduct = LookupOperation.newLookup()
			.from("product")
			.localField("deviceList.product_id")
			.foreignField("product_id")
			.as("productList");

		//查询条件
		Criteria criteria = new Criteria();
		if(!StringUtils.isEmpty(productType)){
			criteria.and("deviceList.product_type_id").is(productType);
		}
		if(!StringUtils.isEmpty(productId)){
			criteria.and("product_id").is(productId);
		}
		if(!StringUtils.isEmpty(deviceId)){
			criteria.and("device_id").is(deviceId);
		}
		MatchOperation matchOperation = new MatchOperation(criteria);
		ProjectionOperation project  = Aggregation.project("device_id","deviceList.device_name","deviceList.product_id","productList.product_name","config_type","create_time");
		//条件查询和分页
		Aggregation aggregation = Aggregation.newAggregation(lookupOperation,leftProduct,matchOperation,project,
			Aggregation.skip((currentPage-1)*pageSize),Aggregation.limit(pageSize));

		return mongoTemplate.aggregate(aggregation,"device_maintenance_record",DeviceMaintenanceRecordDTO.class).getMappedResults();
	}

	/**
	 *说明：获取产品类型列表
	 *@author lilongfei
	 *@since 2019/9/6 15:04
	 */
	public List<ProductType> getProductTypeList(){
		return mongoTemplate.findAll(ProductType.class,"productType");
	}

	/**
	 *说明：获取产品列表
	 *@author lilongfei
	 *@since 2019/9/6 16:14
	 */
	public List<Product> productType(String productType){
		Query query = new Query(Criteria.where("product_type_id").is(productType));
		return mongoTemplate.find(query,Product.class,"product");
	}

	/**
	 *说明：根据产品id查询设备列表
	 *@author lilongfei
	 *@since 2019/9/6 16:39
	 */
	public List<Device> getDeviceListByProductId(String productId){
		ProjectionOperation project  = Aggregation.project("device_id","device_name");
		Criteria criteria = new Criteria();
		criteria.and("product_id").is(productId);
		MatchOperation matchOperation = new MatchOperation(criteria);
		Aggregation aggregation = Aggregation.newAggregation(matchOperation,project);
		return mongoTemplate.aggregate(aggregation,"device",Device.class).getMappedResults();
	}

	/**
	 *说明：恢复默认设置
	 *@author lilongfei
	 *@since 2019/9/10 15:03
	 */
	public long resetDevice(String deviceId){
		Query query = new Query(Criteria.where("device_id").is(deviceId));
		Device device = mongoTemplate.find(query,Device.class).get(0);
		//修改参数
		Update update = new Update();
		update.set("device_name",device.getDeviceName());
		update.set("product_id",device.getProductId());
		update.set("device_firm",device.getProductId());
		update.set("device_firm",device.getProductId());
		update.set("firmware_version",device.getProductId());
		update.set("operate_unit",device.getProductId());
		update.set("maintain_person",device.getProductId());
		update.set("maintain_person_phone",device.getProductId());
		update.set("province",device.getProductId());
		update.set("city",device.getProductId());
		update.set("region",device.getProductId());
		update.set("longitude",device.getProductId());
		update.set("dimension",device.getProductId());
		update.set("ip_address",device.getProductId());
		update.set("describe",device.getProductId());
		update.set("topic",device.getProductId());
		return mongoTemplate.upsert(query,update,"device_default").getModifiedCount();
	}

}
